package model;

import java.util.ArrayList;
import java.util.Observable;

/**
 *Class that contains all the game-logic 
 *for Blackjack.
 */

public class Blackjack extends Observable {

	private ArrayList<Player> players;
	private Player dealer; //Dealer
	private Deck deck;
	private boolean gameover; //Is the game over?
	private long pot;

	//Constructor
	public Blackjack() {

		deck = new Deck();
		players = new ArrayList<Player>();
		dealer = new Player("Mr. Dealer", 0, 0);

	}
	
	//Constructor
		public Blackjack( ArrayList<Player> oldplayers) {

			deck = new Deck();
			players = oldplayers;
			dealer = new Player("Mr. Dealer", 0, 0);

		}


	public void addPlayer(String name, int avatar,long cashAmount) {

		players.add(new Player(name,avatar,cashAmount));


	}

	public int getPlayerPoints(int index) {

		return players.get(index).getPoints();

	}

	public int getDealerPoints() {

		return dealer.getPoints();

	}

	public Hand getPlayerHand(int index) {

		return players.get(index).getHand();

	}

	public Hand getDealerHand() {

		return dealer.getHand();

	}

	public boolean GameOver() {
		if(gameover)
			return true;
		else
			return false;
	}

	public void InitGame() {
		gameover = false;

		deck.shuffleCards();

	}

	public void dealCards() {
		
		deck.shuffleCards();

		for(int i = 0; i < players.size(); i++) {

			PlayerHit(i);PlayerHit(i);

		}

		Hit(dealer); //Adds one card from the deck to the hand of the dealer

	}

	public int checkPoints(int index) {
		
		if(players.get(index).getPoints() == 21) {
			gameover = true;
			return 1; //Player gets 21 points
		}
		else if(players.get(index).getPoints() > 21) {
			gameover = true;
			return 2; //Player busts
		}
		else if(dealer.getPoints() == 21) {
			gameover = true;
			return 3; //Dealer gets 21 points
		}
		else if(dealer.getPoints() > 21) {
			gameover = true;
			return 4; //Dealer busts
		}
		else if(players.get(index).getPoints() == dealer.getPoints()) {
			gameover = true;
			return 5; //Push
		}
		else if(dealer.getPoints() >= 17 && players.get(index).getPoints() > dealer.getPoints()) {
			gameover = true;
			return 6; //Player wins
		}
		else if(dealer.getPoints() >= 17 && players.get(index).getPoints() < dealer.getPoints()) {
			gameover = true;
			return 7; //Dealer wins
		}
		else {
			return 0;
		}
		
	}

	public void PlaceBets(Player p, long amount) throws NotEnoughCashException {

		pot = pot + p.bet(amount)*2;

	}

	public void Payout(boolean playerwon, Player p){

		if (playerwon){
			p.recevicePot(pot);
		}

	}

	protected ArrayList<Player> getPlayers(){
		return players;
	}
	
	public int[] getPlayerAvatars() {

		int[] playerAvatars = new int[players.size()];

		for(int i = 0; i < players.size(); i++) {
			playerAvatars[i] = players.get(i).getAvatar();
		}

		return playerAvatars;

	}

	public long getPot(){
		return pot;
	}

	private void Hit(Player p) {

		try {

			p.receiveCard(deck);

		}catch(NoSuchCardException e) {

			System.out.println(e.getMessage());

		}

		try {
			//Add the points (Blackjack) of the added card to playerPoints
			if(p.getLatestCardRank() == 10 || p.getLatestCardRank() == 11 || p.getLatestCardRank() == 12) { //Face cards
				p.addPoints(10);
			}
			else if(p.getLatestCardRank() == 13) { //Ace
				if(p.getPoints() == 20 || (p.getPoints() + 11) > 21) {
					p.addPoints(1); //Ace counts as 1 if you have 20 points or over 21
				}
				else {
					p.addPoints(11);
				}
			}
			else {
				p.addPoints(p.getLatestCardRank() + 1);
			}
		}catch(NoSuchCardException e) {
			System.out.println(e.getMessage());
		}

	}

	public void PlayerHit(int index) {

		Hit(players.get(index));

		this.setChanged();
		this.notifyObservers(checkPoints(index));
		
		this.setChanged();
		this.notifyObservers(players.get(index));

	}

	public void Stand() {
		while(dealer.getPoints() < 17) {
			Hit(dealer);
		}


	}

	public void Surrender() {
		gameover = true;

		this.setChanged();
		this.notifyObservers();
	}

	public void EndGame() {

		/* Clear the players, dealer and the deck */
		players.removeAll(players);
		dealer = null;
		deck = null;

		this.setChanged();
		this.notifyObservers();

	}



}
